package com.mai.erp.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mai.erp.domain.Dispatch;
import com.mai.erp.domain.Piece;
import com.mai.erp.domain.Process;
import com.mai.erp.domain.Product;
import com.mai.erp.domain.vo.ProductQueueVO;
import com.mai.erp.service.DispatchService;
import com.mai.erp.mapper.DispatchMapper;
import com.mai.erp.service.PieceService;
import com.mai.erp.service.ProcessService;
import com.mai.erp.service.ProductService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wang
 * @description 针对表【dispatch(产品件与工位的调度关系表)】的数据库操作Service实现
 * @createDate 2025-06-16 10:21:26
 */
@Service
@SuppressWarnings("all")
public class DispatchServiceImpl extends ServiceImpl<DispatchMapper, Dispatch>
        implements DispatchService {

    @Resource
    private DispatchMapper dispatchMapper;
    @Resource
    private PieceService pieceService;
    @Resource
    private ProductService productService;
    @Resource
    private ProcessService processService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void proceed(Integer workStationId) {
        updateStatus(workStationId, 1, 2);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void complete(Integer workStationId) {
        updateStatus(workStationId, 2, 3);
    }

    @Override
    public List<ProductQueueVO> getQueueIngDispatches(Integer workStationId) {
        // 队列号 件号 产品号 产品名称 预计耗时 备注
        List<Dispatch> dispatches = this.getQueueIngDispatchesByWsId(6);
        if (CollUtil.isEmpty(dispatches))
            return Collections.emptyList();

        List<ProductQueueVO> vos = dispatches.stream()
                .map(dispatch -> {
                    String queNum = dispatch.getQid();
                    Integer priceNum = dispatch.getPieid();
                    Piece piece = pieceService.getById(priceNum);
                    Integer productId = piece.getPid();
                    Product product = productService.getById(productId);
                    // 映射表里查不到产品的话，那多半是上游的问题，下游没办法，忽略掉这条数据不全的列
                    if (product == null) {
                        return null;
                    }
                    String productName = product.getName();
                    Process process = processService.getByWorkStationIdAndProductId(dispatch.getWsid(), productId);
                    // 同理
                    if (process == null) {
                        return null;
                    }
                    Integer elapsed = process.getElapsed();
                    // 封装结果集并返回
                    ProductQueueVO vo = new ProductQueueVO();
                    vo.setQueueNum(queNum);
                    vo.setPieceId(priceNum);
                    vo.setProductNum(product.getProNum());
                    vo.setProductName(productName);
                    vo.setElapsed(elapsed);
                    return vo;
                })
                .filter(ObjectUtil::isNotNull)
                .collect(Collectors.toList());
        return vos;
    }

    private void updateStatus(Integer workStationId, int beforeStatus, int expectStatus) {
        Dispatch dispatch = getFirstByValid(workStationId, beforeStatus);
        dispatch.setStatus(expectStatus);
        dispatchMapper.updateById(dispatch);
    }

    private Dispatch getFirstByValid(Integer workStationId, Integer beforeStatus) {
        Dispatch dispatch = dispatchMapper.selectOne(
                new LambdaQueryWrapper<Dispatch>()
                        .eq(Dispatch::getWsid, workStationId)
                        .eq(Dispatch::getStatus, beforeStatus)
                        .orderByDesc(Dispatch::getStartingtime)
                        .last("limit 1")
        );
        if (dispatch == null) {
            throw new IllegalArgumentException("当前工位没有" + (beforeStatus == 1 ? "待加工" : "加工中") + "的产品，请检查后再试");
        }
        return dispatch;
    }
}




